#include <idt.h>
#include <textmode.h>
#include <types.h>
#include <io.h>
extern void isr0();
extern void isr1();
extern void isr2();
extern void isr3();
extern void isr4();
extern void isr5();
extern void isr6();
extern void isr7();
extern void isr8();
extern void isr9();
extern void isr10();
extern void isr11();
extern void isr12();
extern void isr13();
extern void isr14();
extern void isr15();
extern void isr16();
extern void isr32();

struct idt_entry idt_entries[256];
struct idt_ptr idt_p;
void idt_set_gate(unsigned char num, unsigned int base, unsigned short sel, unsigned char flags)//thanks jamesm
{
   idt_entries[num].base_lo = base & 0xFFFF;
   idt_entries[num].base_hi = (base >> 16) & 0xFFFF;

   idt_entries[num].sel     = sel;
   idt_entries[num].always0 = 0;
   // We must uncomment the OR below when we get to using user-mode.
   // It sets the interrupt gate's privilege level to 3.
   idt_entries[num].flags   = flags /* | 0x60 */;
}

void idt_install()//install the idt and enable interrupts
{
   kprint("Installing IDT    ");
/*Here is where we set all of our idt entries*/
idt_set_gate(0,cast_uint(isr0),0x08,0x8E);
idt_set_gate(1,cast_uint(isr1),0x08,0x8E);
idt_set_gate(2,cast_uint(isr2),0x08,0x8E);
idt_set_gate(3,cast_uint(isr3),0x08,0x8E);
idt_set_gate(4,cast_uint(isr4),0x08,0x8E);
idt_set_gate(5,cast_uint(isr5),0x08,0x8E);
idt_set_gate(6,cast_uint(isr6),0x08,0x8E);
idt_set_gate(7,cast_uint(isr7),0x08,0x8E);
idt_set_gate(8,cast_uint(isr8),0x08,0x8E);
idt_set_gate(9,cast_uint(isr9),0x08,0x8E);
idt_set_gate(10,cast_uint(isr10),0x08,0x8E);
idt_set_gate(11,cast_uint(isr11),0x08,0x8E);
idt_set_gate(12,cast_uint(isr12),0x08,0x8E);
idt_set_gate(13,cast_uint(isr13),0x08,0x8E);
idt_set_gate(14,cast_uint(isr14),0x08,0x8E);
idt_set_gate(15,cast_uint(isr15),0x08,0x8E);
idt_set_gate(16,cast_uint(isr16),0x08,0x8E);
idt_set_gate(32,cast_uint(isr32),0x08,0x8E);
/*********************************************/
   idt_p.limit = sizeof(struct idt_entry) * 256 -1;
   idt_p.base  = cast_uint(&idt_entries);
   remap_pic();
   idt_flush();//load the idtr with the idt pointer
   kprint("DONE\n");
}

void remap_pic()//for more info check out brokenthorn tuts
{
outb(PICC1,ICW1);//init pic 1
outb(PICC2,ICW1);//init pic 2
outb(PICD1,0x20);//remap irq0-7 to 0x20-0x27
outb(PICD2,0x28);//remap irq8+ to 0x28+
outb(PICD1,0x4);//ICW3
outb(PICD2,0x2);//ICW3 to second pic
outb(PICD1,0x1);//ICW4
outb(PICD2,0x1);//^
outb(PICD1,0);//null out the register values
outb(PICD2,0);
}

void EOI()
{
outb(0x20,0x20);
}//end of int
